<template>
	<el-container class="panel-container">
		<el-tabs :active-name="activeTab" style="height: 100%; overflow: hidden;width: 100%">
			<el-tab-pane :label="$t('designer.hint.widgetSetting')" name="1">
				<el-scrollbar class="setting-scrollbar" :style="{height: scrollerHeight}">
					<template v-if="!!designer.selectedWidget && !designer.selectedWidget.category">
						<el-form :model="optionModel" size="small" label-position="left" label-width="120px" class="setting-form" @submit.prevent>
							<el-collapse v-model="widgetActiveCollapseNames" class="setting-collapse">
								<el-collapse-item name="1" v-if="showCollapse(commonProps)" :title="$t('designer.setting.commonSetting')">
									<template v-for="(editorName, propName) in commonProps" :key="propName">
										<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
												   :designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
									</template>
								</el-collapse-item>

								<el-collapse-item name="2" v-if="showCollapse(advProps)" :title="$t('designer.setting.advancedSetting')">
									<template v-for="(editorName, propName) in advProps" :key="propName">
										<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
												   :designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
									</template>
								</el-collapse-item>

								<el-collapse-item name="3" v-if="showEventCollapse() && showCollapse(eventProps)" :title="$t('designer.setting.eventSetting')">
									<template v-for="(editorName, propName) in eventProps" :key="propName">
										<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
												   :designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"/>
									</template>
								</el-collapse-item>
							</el-collapse>

						</el-form>
					</template>

					<template v-if="(!!designer.selectedWidget && !!designer.selectedWidget.category)">
						<el-form :model="optionModel" size="small" label-position="left" label-width="120px" class="setting-form"
								 @submit.prevent>
							<el-collapse v-model="widgetActiveCollapseNames" class="setting-collapse">
								<el-collapse-item name="1" v-if="showCollapse(commonProps)" :title="$t('designer.setting.commonSetting')">
									<template v-for="(editorName, propName) in commonProps" :key="propName">
										<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
												   :designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
									</template>
								</el-collapse-item>

								<el-collapse-item name="2" v-if="showCollapse(advProps)" :title="$t('designer.setting.advancedSetting')">
									<template v-for="(editorName, propName) in advProps" :key="propName">
										<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
												   :designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
									</template>
								</el-collapse-item>

								<el-collapse-item name="3" v-if="showEventCollapse() && showCollapse(eventProps)" :title="$t('designer.setting.eventSetting')">
									<template v-for="(editorName, propName) in eventProps" :key="propName">
										<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
												   :designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
									</template>
								</el-collapse-item>
							</el-collapse>
						</el-form>
					</template>

				</el-scrollbar>
			</el-tab-pane>

			<el-tab-pane v-if="!!designer" :label="$t('designer.hint.formSetting')" name="2">
				<el-scrollbar class="setting-scrollbar" :style="{height: scrollerHeight}">
					<form-setting :designer="designer" :form-config="formConfig"></form-setting>
				</el-scrollbar>
			</el-tab-pane>
		</el-tabs>

		<div v-if="showWidgetEventDialogFlag" class="" v-drag="['.drag-dialog.el-dialog', '.drag-dialog .el-dialog__header']">
			<el-dialog :title="$t('designer.setting.editWidgetEventHandler')" v-model="showWidgetEventDialogFlag"
					   :show-close="true" custom-class="drag-dialog small-padding-dialog"
					   :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
				<el-alert type="info" :closable="false" :title="eventHeader"></el-alert>
				<code-editor :mode="'javascript'" :readonly="false" v-model="eventHandlerCode" ref="ecEditor"></code-editor>
				<el-alert type="info" :closable="false" title="}"></el-alert>
				<template #footer>
					<div class="dialog-footer">
						<el-button @click="showWidgetEventDialogFlag = false">
							{{ $t('designer.hint.cancel') }}
						</el-button>
						<el-button type="primary" @click="saveEventHandler">
							{{ $t('designer.hint.confirm') }}
						</el-button>
					</div>
				</template>
			</el-dialog>
		</div>
		<table-columns-dialog
			v-if="showTableColumnsDialogFlag"
			v-model="showTableColumnsDialogFlag"
			@closed="showTableColumnsDialogFlag=false"
			@success="handleTableColumnsSuccess"
			:tableColumns="thisSelectedWidget.options.tableColumns"
		>
		</table-columns-dialog>
		<children-table-columns-dialog
			v-if="showChildrenTableColumnsDialogFlag"
			v-model="showChildrenTableColumnsDialogFlag"
			@closed="showChildrenTableColumnsDialogFlag=false"
			@success="handleChildrenTableColumnsSuccess"
			:childrenTableColumns="thisSelectedWidget.options.childrenTableColumns"
		>
		</children-table-columns-dialog>
		<table-data-dialog
			v-if="showTableDataDialogFlag"
			v-model="showTableDataDialogFlag"
			@closed="showTableDataDialogFlag=false"
			@success="handleTableDataSuccess"
			:tableData="thisSelectedWidget.options.tableData"
		>
		</table-data-dialog>
	</el-container>
</template>

<script>
import CodeEditor from '@/components/designer/code-editor/index'
import FormSetting from './form-setting'
import WidgetProperties from './propertyRegister'
import {propertyRegistered} from './propertyRegister'
import {addWindowResizeHandler} from "@/utils/util"
import emitter from "@/utils/emitter";
import PropertyEditors from './property-editor/index'
import EventHandler from './property-editor/event-handler/index.js'
import TableColumnsDialog from "@/components/designer/form-designer/setting-panel/property-editor/datatable/tableColumnsDialog";
import ChildrenTableColumnsDialog from "@/components/designer/form-designer/setting-panel/property-editor/childrendatatable/childrenTableColumnsDialog";
import TableDataDialog from "@/components/designer/form-designer/setting-panel/property-editor/datatable/tableDataDialog";

const {COMMON_PROPERTIES, ADVANCED_PROPERTIES, EVENT_PROPERTIES,SPECIFIC_MACRO_PROPERTIES,SPECIFIC_FETCH_PROPERTIES} = WidgetProperties

export default {
	name: "SettingPanel",
	componentName: "SettingPanel",
	mixins: [emitter],
	components: {
		TableDataDialog,
		TableColumnsDialog,
		ChildrenTableColumnsDialog,
		CodeEditor,
		FormSetting,
		...PropertyEditors,
		...EventHandler
	},
	props: {
		designer: Object,
		selectedWidget: Object,
		formConfig: Object,
	},
	inject: ['getDesignerConfig'],
	data() {
		return {
			thisSelectedWidget : this.selectedWidget,
			designerConfig: this.getDesignerConfig(),
			scrollerHeight: 0,
			activeTab: "2",
			widgetActiveCollapseNames: ['1', '3'], //['1', '2', '3'],
			formActiveCollapseNames: ['1', '2'],
			commonProps: COMMON_PROPERTIES,
			advProps: ADVANCED_PROPERTIES,
			eventProps: EVENT_PROPERTIES,
			macroProps:SPECIFIC_MACRO_PROPERTIES,
			fetchProps:SPECIFIC_FETCH_PROPERTIES,
			showWidgetEventDialogFlag: false,
			showTableColumnsDialogFlag:false,
			showChildrenTableColumnsDialogFlag:false,
			showTableDataDialogFlag:false,
			eventHandlerCode: '',
			curEventName: '',
			eventHeader: '',

			subFormChildWidgetFlag: false,
		}
	},
	computed: {
		optionModel: {
			get() {
				return this.selectedWidget.options
			},
			set(newValue) {
				console.log(newValue);
				//this.selectedWidget.options = newValue
			}
		},
	},
	watch: {
		'selectedWidget':{
			handler(val) {
				this.thisSelectedWidget = val
			}
		},
		'designer.selectedWidget': {
			handler(val) {
				if (val) {
					this.activeTab = "1"
					if(val.type=="input-macro")
					{
						this.commonProps = Object.assign(this.commonProps, this.macroProps);
					}else if(val.type=="input-fetch"||val.type=="flow-relation")
					{
						this.commonProps = Object.assign(this.commonProps, this.fetchProps);
					}
				}
			}
		},
		'selectedWidget.options': {  //组件属性变动后，立即保存表单JSON！！
			deep: true,
			handler(val) {
				this.designer.saveCurrentHistoryStep(val)
			}
		},
		formConfig: {
			deep: true,
			handler() {
				this.designer.saveCurrentHistoryStep()
			}
		},
	},
	created() {
		this.onEvent('editEventHandler', (eventParams) => {
			//debugger
			this.editEventHandler(eventParams[0], eventParams[1])
		})

		this.designer.handleEvent('form-css-updated', (cssClassList) => {
			this.designer.setCssClassList(cssClassList)
		})

		this.onEvent('showTableColumnsDialog', () => {
			//debugger
			this.showTableColumnsDialog()
		})
		this.onEvent('showChildrenTableColumnsDialog', () => {
			//debugger
			this.showChildrenTableColumnsDialog()
		})
		this.onEvent('showTableDataDialog', () => {
			//debugger
			this.showTableDataDialog()
		})
	},
	mounted() {
		if (!this.designer.selectedWidget) {
			this.activeTab = "2"
		} else {
			this.activeTab = "1"
		}
		this.scrollerHeight = window.innerHeight - 56 - 48 + 'px'
		addWindowResizeHandler(() => {
			this.$nextTick(() => {
				this.scrollerHeight = window.innerHeight - 56 - 48 + 'px'
				//console.log(this.scrollerHeight)
			})
		})
	},
	methods: {
		showEventCollapse() {
			if (this.designerConfig['eventCollapse'] === undefined) {
				return true
			}
			return !!this.designerConfig['eventCollapse']
		},
		hasPropEditor(propName, editorName) {
			if (!editorName) {
				return false
			}
			/* alert组件注册了两个type属性编辑器，跳过第一个type属性编辑器，只显示第二个alert-type属性编辑器！！ */
			if (propName.indexOf('-') <= -1) {
				let uniquePropName = this.selectedWidget.type + '-' + propName
				if (propertyRegistered(uniquePropName)) {
					return false
				}
			}
			let originalPropName = propName.replace(this.selectedWidget.type + '-', '')  //去掉组件名称前缀-，如果有的话！！
			return this.designer.hasConfig(this.selectedWidget, originalPropName)
		},
		getPropEditor(propName, editorName) {
			let originalPropName = propName.replace(this.selectedWidget.type + '-', '')  //去掉组件名称前缀-，如果有的话！！
			let ownPropEditorName = `${this.selectedWidget.type}-${originalPropName}-editor`
			//console.log(ownPropEditorName, this.$options.components[ownPropEditorName])
			if (this.$options.components[ownPropEditorName]) {  //局部注册的属性编辑器组件
				return ownPropEditorName
			}
			//return !!this.$root.$options.components[ownPropEditorName] ? ownPropEditorName : editorName  //Vue2全局注册的属性编辑器组件
			return this.$root.$.appContext.components[ownPropEditorName] ? ownPropEditorName : editorName  //Vue3全局注册的属性编辑器组件
		},

		showCollapse(propsObj) {
			let result = false
			for (let propName in propsObj) {
				if (!Object.prototype.hasOwnProperty.call(propsObj, propName)) {
					continue
				}
				if (this.hasPropEditor(propName, propsObj[propName])) {
					result = true
					break
				}
			}
			return result
		},
		editEventHandler(eventName, eventParams) {
			//debugger
			this.curEventName = eventName
			this.eventHeader = `${this.optionModel.name}.${eventName}(${eventParams.join(', ')}) {`
			this.eventHandlerCode = this.selectedWidget.options[eventName] || ''
			// 设置字段校验函数示例代码
			if ((eventName === 'onValidate') && (!this.optionModel['onValidate'])) {
				this.eventHandlerCode = "  /* sample code */\n  /*\n  if ((value > 100) || (value < 0)) {\n    callback(new Error('error message'))  //fail\n  } else {\n    callback();  //pass\n  }\n  */"
			}

			this.showWidgetEventDialogFlag = true
		},
		showTableColumnsDialog()
		{
			this.showTableColumnsDialogFlag = true
		},
		showChildrenTableColumnsDialog()
		{
			this.showChildrenTableColumnsDialogFlag = true
		},
		showTableDataDialog()
		{
			this.showTableDataDialogFlag = true
		},
		saveEventHandler() {
			const codeHints = this.$refs.ecEditor.getEditorAnnotations()
			let syntaxErrorFlag = false
			if (!!codeHints && (codeHints.length > 0)) {
				codeHints.forEach((chItem) => {
					if (chItem.type === 'error') {
						syntaxErrorFlag = true
					}
				})

				if (syntaxErrorFlag) {
					this.$message.error(this.$t('designer.setting.syntaxCheckWarning'))
					return
				}
			}
			this.thisSelectedWidget.options[this.curEventName] = this.eventHandlerCode
			this.showWidgetEventDialogFlag = false
		},
		handleTableColumnsSuccess(data)
		{
			this.thisSelectedWidget.options.tableColumns = data;
			this.showTableColumnsDialogFlag=false;
		},
		handleChildrenTableColumnsSuccess(data)
		{
			this.thisSelectedWidget.options.childrenTableColumns = data;
			this.showChildrenTableColumnsDialogFlag=false;
		},
		handleTableDataSuccess(data)
		{
			this.thisSelectedWidget.options.tableData = data;
			//this.thisSelectedWidget.options.tableData = JSON.parse(data);
			this.showTableDataDialogFlag=false;
		}
	}
}
</script>

<style lang="scss" scoped>
.panel-container {
	padding: 0 8px;
	width: 100%;
}
.el-tabs--top{
	:deep(.el-tabs__header) {
		margin: 0px;
	}
}

.setting-scrollbar {
	:deep(.el-scrollbar__wrap) {
		overflow-x: hidden; /* IE浏览器隐藏水平滚动条箭头！！ */
	}
}

.setting-collapse {
	:deep(.el-collapse-item__content) {
		padding-bottom: 6px;
	}

	:deep(.el-collapse-item__header) {
		font-style: italic;
		font-weight: bold;
	}
}

.setting-form {
	:deep(.el-form-item__label) {
		font-size: 13px;
		//text-overflow: ellipsis;
		overflow: hidden;
		white-space: nowrap;
	}

	:deep(.el-form-item--small.el-form-item) {
		margin-bottom: 10px;
	}
}

/* 隐藏Chrome浏览器中el-input数字输入框右侧的上下调整小箭头 */
:deep(.hide-spin-button) input::-webkit-outer-spin-button,
:deep(.hide-spin-button) input::-webkit-inner-spin-button {
	-webkit-appearance: none !important;
}

/* 隐藏Firefox浏览器中el-input数字输入框右侧的上下调整小箭头 */
:deep(.hide-spin-button) input[type="number"] {
	-moz-appearance: textfield;
}

:deep(.custom-divider.el-divider--horizontal) {
	margin: 10px 0;
}

:deep(.custom-divider-margin-top.el-divider--horizontal) {
	margin: 20px 0;
}

.small-padding-dialog {
	:deep(.el-dialog__body) {
		padding: 6px 15px 12px 15px;
	}
}

</style>
